using System;
using System.Collections.Generic;
using System.Text;
using MIMPGameLibrary;
using System.Collections.ObjectModel;

namespace MIMPWinForms.MIMPGameServices
{
    /// <summary>
    /// Defines an interface whose primary purpose is to fire events that describe changes to the game state. 
    /// </summary>
    public interface IGameStateEventsService
    {
        /// <summary>
        /// Occurs when a new Monster is added to the game. EventData is the new Monster.
        /// </summary>
        event EventHandler<EventArgs<Monster>> MonsterAdded;
        /// <summary>
        /// Occurs when a Monster is removed from the game. EventData is the removed Monster.
        /// </summary>
        event EventHandler<EventArgs<Monster>> MonsterRemoved;
        /// <summary>
        /// Occurs when a Monster is moved to a different Hex. EventData is the Monster who moved 
        /// (use its Location property to get the Hex it moved to).
        /// </summary>
        event EventHandler<EventArgs<Monster>> MonsterMoved;
        /// <summary>
        /// Occurs when the list of currently selected Monsters changes. EventData is the selected Monster.
        /// </summary>
        event EventHandler<EventArgs<Monster>> SelectedMonsterChanged;
        /// <summary>
        /// Occurs when the user has chosen a target to attack, and should now select additional attackers. 
        /// EventData is the Monster being targeted.
        /// </summary>
        event EventHandler<EventArgs<Monster>> AttackTargetChosen;
        /// <summary>
        /// Occurs when the list of monsters preparing to attack the target changes. 
        /// </summary>
        event EventHandler<EventArgs<List<Monster>>> AttackersChanged;
        /// <summary>
        /// Occurs when the list of monsters assisting in defense changes. 
        /// </summary>
        event EventHandler<EventArgs<List<Monster>>> DefendersChanged;
        /// <summary>
        /// Occurs when the attacking player has finished selecting all attackers, and the defending player should now select defenders.
        /// </summary>
        event EventHandler<EventArgs<List<Monster>, Monster>> AttackersFinalized;
        /// <summary>
        /// Occurs when the game has determined who won and lost the attack; at this point the losing player must
        /// decide how to divide the damage up among his Monsters. EventData is an AttackResult object describing 
        /// the outcome of the attack.
        /// </summary>
        event EventHandler<EventArgs<AttackResult>> AttackResultCalculated;
        /// <summary>
        /// Occurs when the attack has been completed and damage assigned to the losing Monsters.
        /// EventData is a list of all Monsters who took damage in the attack.
        /// </summary>
        event EventHandler<EventArgs<List<Monster>>> AttackCompleted;
        /// <summary>
        /// Occurs when an action that the user attempted to take failed. 
        /// EventData is a string explaining the error.
        /// </summary>
        event EventHandler<EventArgs<string>> ActionFailed;
        /// <summary>
        /// Occurs whenever one of the game's ControlPoints is updated with a new owner or a new control strength.
        /// EventData is the ControlPoint that changed.
        /// </summary>
        event EventHandler<EventArgs<ControlPoint>> ControlPointChanged;
        /// <summary>
        /// Occurs when one Player's turn ends and the next's begins. EventData is the Player whose turn just started.
        /// </summary>
        event EventHandler<EventArgs<Player>> NewTurnBegan;
        /// <summary>
        /// Occurs when a Player is eliminated from the game. EventData is the Player who lost.
        /// </summary>
        event EventHandler<EventArgs<Player>> PlayerLost;
        /// <summary>
        /// Occurs when someone wins the game. EventData is the Player who won.
        /// </summary>
        event EventHandler<EventArgs<Player>> PlayerWon;
        /// <summary>
        /// Occurs when a Monster uses an action to get a second move. EventData is the Monster in question.
        /// </summary>
        event EventHandler<EventArgs<Monster>> MonsterTookSecondMove;
        /// <summary>
        /// Occurs when control of the game state updates passes to a different Player. EventData is the Player who now has control.
        /// </summary>
        event EventHandler<EventArgs<Player>> ActivePlayerChanged;
        /// <summary>
        /// Occurs when the number of deployment points a Player has left changes. 
        /// EventData is the Player whose points changed; to get the number of points he/she now has, use Player.DeploymentPoints.
        /// </summary>
        event EventHandler<EventArgs<Player>> PlayersDeploymentPointsChanged;
        /// <summary>
        /// Occurs when the game phase changes. EventData is the phase the game is now in.
        /// </summary>
        event EventHandler<EventArgs<GameState.Phases>> GamePhaseChanged;
        /// <summary>
        /// Occurs when the Hexes that make up the game map change. EventData is a List of the Hexes that are now in the game.
        /// </summary>
        event EventHandler<EventArgs<List<Hex>>> MapChanged;
        /// <summary>
        /// Occurs when the game sends a message that should be displayed to the players. 
        /// EventData is a string containing the message to display.
        /// </summary>
        event EventHandler<EventArgs<string>> ApplicationMessageSent;
        /// <summary>
        /// Occurs when a player sends a chat message that should be displayed to all players. 
        /// PrimaryEventData is the Player who sent the message.
        /// SecondaryEventData is a string containing the message sent.
        /// </summary>
        event EventHandler<EventArgs<Player, string>> ChatYellSent;
        /// <summary>
        /// Occurs when a player sends a chat message that should be displayed to a group of players.
        /// PrimaryEventData is the Player who sent the message.
        /// SecondaryEventData is a string containing the message sent.
        /// TertiaryEventData is a List of Players who should see the message.
        /// </summary>
        event EventHandler<EventArgs<Player, string, List<Player>>> ChatSaySent;
        /// <summary>
        /// Occurs when a player sends a message that should be dispalyed to only one other player.
        /// PrimaryEventData is the Player who sent the message.
        /// SecondaryEventData is a string containing the message sent.
        /// TertiaryEventData is the Player who should see the message.
        /// </summary>
        event EventHandler<EventArgs<Player, string, Player>> ChatWhisperSent;

        /// <summary>
        /// A list of the Players in the game.
        /// </summary>
        ReadOnlyCollection<Player> Players { get; }

        /// <summary>
        /// A list of the Hexes in the game.
        /// </summary>
        List<Hex> Hexes { get; }

        /// <summary>
        /// Starts the game.
        /// </summary>
        void StartGame();
    }
}
